home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / network / samba / patches / samba-1.037 / samba-1
Encoding:
Text File  |  1995-07-11  |  49.1 KB  |  1,821 lines

  1. diff -u -r --new-file last-version/docs/ENCRYPTION.txt samba-1.9.14alpha11/docs/ENCRYPTION.txt
  2. --- last-version/docs/ENCRYPTION.txt    Thu Jan  1 10:00:00 1970
  3. +++ samba-1.9.14alpha11/docs/ENCRYPTION.txt    Tue Jul 11 22:37:36 1995
  4. @@ -0,0 +1,40 @@
  5. +This is a very brief description on how to setup samba to support
  6. +password encryption. More complete instructions will probably be added
  7. +later.
  8. +
  9. +1) get and compile the libdes libraries. the source is available from
  10. +nimbus.anu.edu.au in pub/tridge/libdes/libdes.tar.92-10-13.gz
  11. +
  12. +2) enable the encryption stuff in the Samba makefile, making sure you
  13. +point it to the libdes library and include file (it needs des.h)
  14. +
  15. +3) compile and install samba as usual
  16. +
  17. +4) enable encrypted passwords in smb.conf by adding the line 
  18. +"encrypt passwords = yes" in the [global] section
  19. +
  20. +5) create the initial smbpasswd password file in the place you
  21. +specified in the Makefile. A simple way to do this based on your
  22. +existing Makefile (assuming it is in a reasonably standard format) is
  23. +like this:
  24. +
  25. +cat /etc/passwd | mksmbpasswd.sh > /usr/local/samba/private/smbpasswd
  26. +
  27. +note that the mksmbpasswd.sh script is in the samba source directory.
  28. +
  29. +If this fails then you will find that you will need entries that look
  30. +like this:
  31. +
  32. +# SMB password file.
  33. +tridge:148:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:Andrew Tridgell:/home/tridge:/bin/tcsh
  34. +
  35. +note that the uid and username fields must be right. Also try to get
  36. +the number of X's right (there should be 32).
  37. +
  38. +6) set the passwords for users using the smbpasswd command. For
  39. +example, as root you could do "smbpasswd tridge"
  40. +
  41. +7) try it out!
  42. +
  43. +Note that you can test things using smbclient, as it also now supports
  44. +encryption.
  45. diff -u -r --new-file last-version/examples/tridge/smb.conf samba-1.9.14alpha11/examples/tridge/smb.conf
  46. --- last-version/examples/tridge/smb.conf    Thu Jun 29 22:10:12 1995
  47. +++ samba-1.9.14alpha11/examples/tridge/smb.conf    Tue Jul 11 20:12:35 1995
  48. @@ -1,7 +1,8 @@
  49. -[global]
  50. +[global]   
  51.     config file = /usr/local/samba/smb.conf.%m
  52.     status = yes
  53.     security = user
  54. +   encrypt passwords = yes
  55.     server string = Tridge (%v,%h)
  56.     load printers = yes
  57.     log level = 1
  58. diff -u -r --new-file last-version/source/Makefile samba-1.9.14alpha11/source/Makefile
  59. --- last-version/source/Makefile    Tue Jul 11 16:28:48 1995
  60. +++ samba-1.9.14alpha11/source/Makefile    Tue Jul 11 20:53:41 1995
  61. @@ -419,7 +419,7 @@
  62.  INCLUDES2 = pcap.h trans2.h reply.h
  63.  INCLUDES = $(INCLUDES1) $(INCLUDES2)
  64.  
  65. -UTILOBJ = util.o charset.o kanji.o fault.o
  66. +UTILOBJ = util.o charset.o kanji.o fault.o smbencrypt.o
  67.  PARAMOBJ = $(UTILOBJ) loadparm.o params.o pcap.o access.o username.o ufc.o smbpass.o
  68.  SMBDOBJ1 = $(PARAMOBJ) trans2.o message.o dir.o printing.o locking.o
  69.  SMBDOBJ2 = ipc.o reply.o mangle.o chgpasswd.o password.o
  70. diff -u -r --new-file last-version/source/change-log samba-1.9.14alpha11/source/change-log
  71. --- last-version/source/change-log    Tue Jul 11 16:47:34 1995
  72. +++ samba-1.9.14alpha11/source/change-log    Tue Jul 11 22:38:22 1995
  73. @@ -1519,6 +1519,13 @@
  74.      - added "passwd chat" option and chat interpretation code
  75.      - added "smb passwd file" option
  76.      - released alpha10
  77. +    - cleaned up chgpasswd.c a little
  78. +    - portability changes to the encryption handling code
  79. +    - added password encryption to smbclient
  80. +    - fixed a share level security encryption bug
  81. +    - added "ENCRYPTION.txt" document
  82. +    - released alpha11
  83. +
  84.  
  85.  ==========
  86.  todo:
  87. diff -u -r --new-file last-version/source/chgpasswd.c samba-1.9.14alpha11/source/chgpasswd.c
  88. --- last-version/source/chgpasswd.c    Tue Jul 11 16:32:38 1995
  89. +++ samba-1.9.14alpha11/source/chgpasswd.c    Tue Jul 11 18:12:10 1995
  90. @@ -9,16 +9,9 @@
  91.   * was included as a client to change passwords using the 'passwd' program
  92.   * on the remote machine.
  93.   *
  94. - * It has been dissected and recreated in a form that allows passwd changing for
  95. - * a valid user (user is already validated BEFORE this routine is run). It compares
  96. - * the user name to those in the LOCAL password file and, if they are found, it 
  97. - * runs 'passwd.'  If not, however, it assumes, since the person has already been 
  98. - * validated, that they are an NIS user and it uses 'yppasswd.' 
  99. - *
  100.   * This routine is called by set_user_password() in password.c only if ALLOW_PASSWORD_CHANGE
  101.   * is defined in the compiler directives located in the Makefile.
  102.   *
  103. - *
  104.   * This code has been hacked by Bob Nance (nance@niehs.nih.gov) and Evan Patterson
  105.   * (patters2@niehs.nih.gov) at the National Institute of Environmental Health Sciences
  106.   * and rights to modify, distribute or incorporate this change to the CAP suite or
  107. @@ -35,126 +28,35 @@
  108.  #define MINPASSWDLENGTH 5
  109.  #define BUFSIZE 512
  110.  
  111. -static int findpty (char **slave);
  112. -static int talktochild(int master,char *oldpass,char *newpass,char *emess);
  113. -static int dochild(int master,char *slavedev,char *name,char *oldpass,char *newpass);
  114. -static int expect(int master,char *expected,char *buf);
  115. -static void writestring (int fd,char *s);
  116. -
  117. -BOOL chgpasswd(char *name,char *oldpass,char *newpass)
  118. +static int findpty(char **slave)
  119.  {
  120. -  char emess[255];
  121. -  char *slavedev;
  122. -  struct passwd *getpwnam();
  123.    int master;
  124. -  pid_t pid, wpid;
  125. -  int wstat;
  126. -  BOOL chstat;
  127. -  int putpwent();
  128. -  
  129. -  strlower(name); 
  130. -  DEBUG(3,("Password change for user: %s\n",name));
  131. -#if DEBUG_PASSWORD
  132. -  DEBUG(100,("Passwords: old=%s new=%s\n",oldpass,newpass)); 
  133. -#endif
  134. -  
  135. -  /* Take the passed information and test it for minimum criteria */
  136. -  /* Minimum password length */
  137. -  if (strlen(newpass) < MINPASSWDLENGTH) /* too short, must be at least MINPASSWDLENGTH */ 
  138. -    {
  139. -      DEBUG(2,("Password Change: %s, New password is shorter than MINPASSWDLENGTH\n",name));
  140. -      return (False);        /* inform the user */
  141. -    }
  142. +  static char line[12] = "/dev/ptyXX";
  143. +  void *dirp;
  144. +  char *dpname;
  145.    
  146. -  /* Password is same as old password */
  147. -  if (strncmp(oldpass,newpass,8) == 0) /* don't allow same password */
  148. -    {
  149. -      DEBUG(2,("Password Change: %s, New password is same as old\n",name)); /* log the attempt */
  150. -      return (False);        /* inform the user */
  151. -    }
  152. -
  153. -  /* That done, let's attempt to actually change the password */
  154. -  /* allocate a pseudo-terminal device */
  155. -  if ((master = findpty (&slavedev)) < 0)
  156. -    {
  157. -      DEBUG(3,("Cannot Allocate pty for password change: %s",name));
  158. -      return(False);
  159. -    }
  160. -
  161. -  if ((pid = fork()) < 0)
  162. -    {
  163. -      DEBUG(3,("Cannot fork() child for password change: %s",name));
  164. -      return(False);
  165. -    }
  166. -
  167. -  /* we now have a pty */
  168. -  if (pid > 0){            /* This is the parent process */
  169. -    if ((chstat = talktochild (master, oldpass, newpass, emess)) == False)
  170. -      {
  171. -    DEBUG(3,("Child failed to change password: %s\n",name));
  172. -    kill(pid, SIGKILL); /* be sure to end this process */
  173. -    return(False);
  174. +  dirp = OpenDir("/dev");
  175. +  if (!dirp) return(-1);
  176. +  while ((dpname = ReadDirName(dirp)) != NULL) {
  177. +    if (strncmp(dpname, "pty", 3) == 0 && strlen(dpname) == 5) {
  178. +      line[8] = dpname[3];
  179. +      line[9] = dpname[4];
  180. +      if ((master = open(line, O_RDWR)) >= 0) {
  181. +    line[5] = 't';
  182. +    *slave = line;
  183. +    CloseDir(dirp);
  184. +    return (master);
  185.        }
  186. -    if ((wpid = waitpid (pid, &wstat, 0)) < 0) {
  187. -      DEBUG(3,("The process is no longer waiting!\n\n"));
  188. -      return(False);
  189. -    }
  190. -    if (pid != wpid) {
  191. -      DEBUG(3,("We were waiting for the wrong process ID\n"));    
  192. -      return(False);
  193.      }
  194. -    if (WIFEXITED (wstat) == 0) {
  195. -      DEBUG(3,("The process exited while we were waiting\n"));
  196. -      return(False);
  197. -    }
  198. -    if (WEXITSTATUS (wstat) != 0) {
  199. -      DEBUG(3,("The status of the process exiting was %d\n", wstat));
  200. -      return(False);
  201. -    }
  202. -
  203.    }
  204. -  else                /* CHILD */
  205. -    {
  206. -      struct passwd *pass = Get_Pwnam(name,True);
  207. -      int gid = pass->pw_gid;
  208. -      int uid = pass->pw_uid;
  209. -
  210. -      /* make us completely into the right uid */
  211. -#ifdef USE_SETRES
  212. -      setresgid(0,0,0);
  213. -      setresuid(0,0,0);
  214. -      setresgid(gid,gid,gid);
  215. -      setresuid(uid,uid,uid);      
  216. -#else      
  217. -      setuid(0);
  218. -      seteuid(0);
  219. -      setgid(gid);
  220. -      setegid(gid);
  221. -      setuid(uid);
  222. -      seteuid(uid);
  223. -#endif
  224. -
  225. -      /* make sure it doesn't freeze */
  226. -      alarm(10);
  227. -
  228. -      DEBUG(3,("Dochild for user %s (uid=%d,gid=%d)\n",name,getuid(),getgid()));
  229. -      chstat = dochild (master, slavedev, name, oldpass, newpass);
  230. -    }
  231. -  DEBUG(3,("Password change %ssuccessful for user %s\n", (chstat?"":"un"), name));
  232. -  return (chstat);
  233. +  CloseDir(dirp);
  234. +  return (-1);
  235.  }
  236.  
  237. -static int dochild (master, slavedev, name, oldpass, newpass)
  238. -     int master;
  239. -     char *slavedev, *name, *oldpass, *newpass;
  240. +static int dochild(int master,char *slavedev, char *passwordprogram)
  241.  {
  242.    int slave;
  243.    struct termios stermios;
  244. -  string passwordprogram;
  245. -    
  246. -  strcpy(passwordprogram,lp_passwd_program());
  247. -
  248. -  string_sub(passwordprogram,"%u",name);
  249.  
  250.    /* Start new session - gets rid of controlling terminal. */
  251.    if (setsid() < 0) {
  252. @@ -214,40 +116,66 @@
  253.    return(True);
  254.  }
  255.  
  256. -static void pwd_sub(char *buf,char *oldpass,char *newpass)
  257. +static int expect(int master,char *expected,char *buf)
  258. +{
  259. +  int n, m;
  260. +  n = 0;
  261. +  buf[0] = 0;
  262. +  while (1) {
  263. +    if (n >= BUFSIZE-1) {
  264. +      return False;
  265. +    }
  266. +
  267. +    /* allow 4 seconds for some output to appear */
  268. +    m = read_with_timeout(master, buf+n, 1, BUFSIZE-1-n, 4000, True);
  269. +    if (m < 0) 
  270. +      return False;
  271. +
  272. +    n += m;
  273. +    buf[n] = 0;
  274. +
  275. +    {
  276. +      pstring s1,s2;
  277. +      strcpy(s1,buf);
  278. +      strcpy(s2,expected);
  279. +      if (do_match(s1, s2, False))
  280. +    return(True);
  281. +    }
  282. +  }
  283. +}
  284. +
  285. +static void pwd_sub(char *buf)
  286.  {
  287. -  string_sub(buf,"%o",oldpass);
  288. -  string_sub(buf,"%n",newpass);
  289.    string_sub(buf,"\\n","\n");
  290.    string_sub(buf,"\\r","\r");
  291.    string_sub(buf,"\\s"," ");
  292.    string_sub(buf,"\\t","\t");
  293.  }
  294.  
  295. -static int talktochild (master, oldpass, newpass, emess)
  296. -     int master;
  297. -     char *oldpass, *newpass, *emess;
  298. +static void writestring(int fd,char *s)
  299. +{
  300. +  int l;
  301. +  
  302. +  l = strlen (s);
  303. +  write (fd, s, l);
  304. +}
  305. +
  306. +
  307. +static int talktochild(int master, char *chatsequence)
  308.  {
  309.    char buf[BUFSIZE];
  310. -  char pswd[BUFSIZE+1];
  311.    int count=0;
  312. -  char *chatsequence = lp_passwd_chat();
  313.    char *ptr=chatsequence;
  314.    fstring chatbuf;
  315.  
  316. -  if (!*chatsequence) {
  317. -    DEBUG(0,("No passwd chat sequence - aborting password change\n"));
  318. -  }
  319. -
  320.    *buf = 0;
  321. -  *pswd = 0;
  322. -  *emess = 0;
  323.    sleep(1);
  324.  
  325.    while (next_token(&ptr,chatbuf,NULL)) {
  326.      BOOL ok=True;
  327.      count++;
  328. -    pwd_sub(chatbuf,oldpass,newpass);
  329. +    pwd_sub(chatbuf);
  330.      if (!strequal(chatbuf,"."))
  331.        ok = expect(master,chatbuf,buf);
  332.  
  333. @@ -261,7 +189,7 @@
  334.      }
  335.  
  336.      if (!next_token(&ptr,chatbuf,NULL)) break;
  337. -    pwd_sub(chatbuf,oldpass,newpass);
  338. +    pwd_sub(chatbuf);
  339.      if (!strequal(chatbuf,"."))
  340.        writestring(master,chatbuf);
  341.  
  342. @@ -275,68 +203,132 @@
  343.    return (True);
  344.  }
  345.  
  346. -static int expect(int master,char *expected,char *buf)
  347. +
  348. +BOOL chat_with_program(char *passwordprogram,char *name,char *chatsequence)
  349.  {
  350. -  int n, m;
  351. -  n = 0;
  352. -  buf[0] = 0;
  353. -  while (1) {
  354. -    if (n >= BUFSIZE-1) {
  355. -      return False;
  356. -    }
  357. +  char *slavedev;
  358. +  int master;
  359. +  pid_t pid, wpid;
  360. +  int wstat;
  361. +  BOOL chstat;    
  362.  
  363. -    /* allow 4 seconds for some output to appear */
  364. -    m = read_with_timeout(master, buf+n, 1, BUFSIZE-1-n, 4000, True);
  365. -    if (m < 0) 
  366. -      return False;
  367. +  /* allocate a pseudo-terminal device */
  368. +  if ((master = findpty (&slavedev)) < 0) {
  369. +    DEBUG(3,("Cannot Allocate pty for password change: %s",name));
  370. +    return(False);
  371. +  }
  372.  
  373. -    n += m;
  374. -    buf[n] = 0;
  375. +  if ((pid = fork()) < 0) {
  376. +    DEBUG(3,("Cannot fork() child for password change: %s",name));
  377. +    return(False);
  378. +  }
  379.  
  380. -    {
  381. -      pstring s1,s2;
  382. -      strcpy(s1,buf);
  383. -      strcpy(s2,expected);
  384. -      if (do_match(s1, s2, False))
  385. -    return(True);
  386. +  /* we now have a pty */
  387. +  if (pid > 0){            /* This is the parent process */
  388. +    if ((chstat = talktochild(master, chatsequence)) == False) {
  389. +      DEBUG(3,("Child failed to change password: %s\n",name));
  390. +      kill(pid, SIGKILL); /* be sure to end this process */
  391. +      return(False);
  392. +    }
  393. +    if ((wpid = waitpid(pid, &wstat, 0)) < 0) {
  394. +      DEBUG(3,("The process is no longer waiting!\n\n"));
  395. +      return(False);
  396. +    }
  397. +    if (pid != wpid) {
  398. +      DEBUG(3,("We were waiting for the wrong process ID\n"));    
  399. +      return(False);
  400. +    }
  401. +    if (WIFEXITED(wstat) == 0) {
  402. +      DEBUG(3,("The process exited while we were waiting\n"));
  403. +      return(False);
  404. +    }
  405. +    if (WEXITSTATUS(wstat) != 0) {
  406. +      DEBUG(3,("The status of the process exiting was %d\n", wstat));
  407. +      return(False);
  408.      }
  409. +    
  410. +  } else {
  411. +    /* CHILD */
  412. +    struct passwd *pass = Get_Pwnam(name,True);
  413. +    int gid = pass->pw_gid;
  414. +    int uid = pass->pw_uid;
  415. +
  416. +    /* make us completely into the right uid */
  417. +#ifdef USE_SETRES
  418. +    setresgid(0,0,0);
  419. +    setresuid(0,0,0);
  420. +    setresgid(gid,gid,gid);
  421. +    setresuid(uid,uid,uid);      
  422. +#else      
  423. +    setuid(0);
  424. +    seteuid(0);
  425. +    setgid(gid);
  426. +    setegid(gid);
  427. +    setuid(uid);
  428. +    seteuid(uid);
  429. +#endif
  430. +
  431. +    /* make sure it doesn't freeze */
  432. +    alarm(20);
  433. +
  434. +    DEBUG(3,("Dochild for user %s (uid=%d,gid=%d)\n",name,getuid(),getgid()));
  435. +    chstat = dochild(master, slavedev, passwordprogram);
  436.    }
  437. +  DEBUG(3,("Password change %ssuccessful for user %s\n", (chstat?"":"un"), name));
  438. +  return (chstat);
  439.  }
  440.  
  441.  
  442. -static void writestring (int fd,char *s)
  443. +BOOL chgpasswd(char *name,char *oldpass,char *newpass)
  444.  {
  445. -  int l;
  446. -  
  447. -  l = strlen (s);
  448. -  write (fd, s, l);
  449. -}
  450. +  pstring passwordprogram;
  451. +  pstring chatsequence;
  452.  
  453. -static int findpty (char **slave)
  454. -{
  455. -  int master;
  456. -  static char line[12] = "/dev/ptyXX";
  457. -  void *dirp;
  458. -  char *dpname;
  459. +  strlower(name); 
  460. +  DEBUG(3,("Password change for user: %s\n",name));
  461. +
  462. +#if DEBUG_PASSWORD
  463. +  DEBUG(100,("Passwords: old=%s new=%s\n",oldpass,newpass)); 
  464. +#endif
  465. +
  466. +  /* Take the passed information and test it for minimum criteria */
  467. +  /* Minimum password length */
  468. +  if (strlen(newpass) < MINPASSWDLENGTH) /* too short, must be at least MINPASSWDLENGTH */ 
  469. +    {
  470. +      DEBUG(2,("Password Change: %s, New password is shorter than MINPASSWDLENGTH\n",name));
  471. +      return (False);        /* inform the user */
  472. +    }
  473.    
  474. -  dirp = OpenDir("/dev");
  475. -  if (!dirp) return(-1);
  476. -  while ((dpname = ReadDirName(dirp)) != NULL) {
  477. -    if (strncmp(dpname, "pty", 3) == 0 && strlen(dpname) == 5) {
  478. -      line[8] = dpname[3];
  479. -      line[9] = dpname[4];
  480. -      if ((master = open(line, O_RDWR)) >= 0) {
  481. -    line[5] = 't';
  482. -    *slave = line;
  483. -    CloseDir(dirp);
  484. -    return (master);
  485. -      }
  486. +  /* Password is same as old password */
  487. +  if (strcmp(oldpass,newpass) == 0) /* don't allow same password */
  488. +    {
  489. +      DEBUG(2,("Password Change: %s, New password is same as old\n",name)); /* log the attempt */
  490. +      return (False);        /* inform the user */
  491.      }
  492. +
  493. +  strcpy(passwordprogram,lp_passwd_program());
  494. +  strcpy(chatsequence,lp_passwd_chat());
  495. +
  496. +  if (!*chatsequence) {
  497. +    DEBUG(2,("Null chat sequence - no password changing\n"));
  498. +    return(False);
  499.    }
  500. -  CloseDir(dirp);
  501. -  return (-1);
  502. +
  503. +  if (!*passwordprogram) {
  504. +    DEBUG(2,("Null password program - no password changing\n"));
  505. +    return(False);
  506. +  }
  507. +
  508. +  string_sub(passwordprogram,"%u",name);
  509. +  string_sub(passwordprogram,"%o",oldpass);
  510. +  string_sub(passwordprogram,"%n",newpass);
  511. +
  512. +  string_sub(chatsequence,"%u",name);
  513. +  string_sub(chatsequence,"%o",oldpass);
  514. +  string_sub(chatsequence,"%n",newpass);
  515. +  return(chat_with_program(passwordprogram,name,chatsequence));
  516.  }
  517. +
  518.  #else
  519.  BOOL chgpasswd(char *name,char *oldpass,char *newpass)
  520.  {
  521. diff -u -r --new-file last-version/source/client.c samba-1.9.14alpha11/source/client.c
  522. --- last-version/source/client.c    Mon Jul 10 09:43:19 1995
  523. +++ samba-1.9.14alpha11/source/client.c    Tue Jul 11 22:12:37 1995
  524. @@ -36,6 +36,9 @@
  525.  BOOL connect_as_printer = False;
  526.  BOOL connect_as_ipc = False;
  527.  
  528. +char cryptkey[8];
  529. +BOOL doencrypt=False;
  530. +
  531.  extern pstring user_socket_options;
  532.  
  533.  /* 30 second timeout on most commands */
  534. @@ -2603,9 +2606,8 @@
  535.    int sesskey=0;
  536.    time_t servertime = 0;
  537.    extern int serverzone;
  538. -  int sec_mode;
  539. +  int sec_mode=0;
  540.    int crypt_len;
  541. -
  542.    struct {
  543.      int prot;
  544.      char *name;
  545. @@ -2711,6 +2713,7 @@
  546.      writebraw_supported = ((SVAL(inbuf,smb_vwv5) & 0x2) != 0);
  547.        }
  548.      crypt_len = smb_buflen(inbuf);
  549. +    memcpy(cryptkey,smb_buf(inbuf),8);
  550.      DEBUG(3,("max mux %d\n",SVAL(inbuf,smb_vwv3)));
  551.      DEBUG(3,("max vcs %d\n",SVAL(inbuf,smb_vwv4)));
  552.      DEBUG(3,("max blk %d\n",SVAL(inbuf,smb_vwv5)));
  553. @@ -2723,6 +2726,7 @@
  554.      servertime = interpret_long_date(inbuf+smb_vwv11+1);
  555.      servertime -= serverzone;
  556.      crypt_len = CVAL(inbuf,smb_vwv16+1);
  557. +    memcpy(cryptkey,smb_buf(inbuf),8);
  558.      if (IVAL(inbuf,smb_vwv9+1) & 1)
  559.        readbraw_supported = writebraw_supported = True;      
  560.      DEBUG(3,("max mux %d\n",SVAL(inbuf,smb_vwv1+1)));
  561. @@ -2736,6 +2740,8 @@
  562.    DEBUG(3,("Got %d byte crypt key\n",crypt_len));
  563.    DEBUG(3,("Chose protocol [%s]\n",prots[SVAL(inbuf,smb_vwv0)].name));
  564.  
  565. +  doencrypt = ((sec_mode & 2) != 0);
  566. +
  567.    if (servertime) {
  568.      static BOOL done_time = False;
  569.      if (!done_time) {
  570. @@ -2755,13 +2761,28 @@
  571.  
  572.    if (Protocol >= PROTOCOL_LANMAN1 && use_setup)
  573.      {
  574. +      fstring pword;
  575. +      int passlen = strlen(pass)+1;
  576. +      strcpy(pword,pass);      
  577. +
  578. +#ifdef SMB_PASSWD
  579. +      if (doencrypt) {
  580. +    DEBUG(3,("Using encrypted passwords\n"));
  581. +    passlen = 24;
  582. +    SMBencrypt(pass,cryptkey,pword);
  583. +      }
  584. +#else
  585. +      doencrypt = False;
  586. +#endif
  587.  
  588. +      /* if in share level security then don't send a password now */
  589. +      if (!(sec_mode & 1)) passlen=0;
  590.  
  591.        /* send a session setup command */
  592.        bzero(outbuf,smb_size);
  593.  
  594.        if (Protocol < PROTOCOL_NT1) {
  595. -    set_message(outbuf,10,2 + strlen(username) + strlen(pass),True);
  596. +    set_message(outbuf,10,1 + strlen(username) + passlen,True);
  597.      CVAL(outbuf,smb_com) = SMBsesssetupX;
  598.      setup_pkt(outbuf);
  599.  
  600. @@ -2770,12 +2791,13 @@
  601.      SSVAL(outbuf,smb_vwv3,2);
  602.      SSVAL(outbuf,smb_vwv4,getpid());
  603.      SIVAL(outbuf,smb_vwv5,sesskey);
  604. -    SSVAL(outbuf,smb_vwv7,strlen(pass)+1);
  605. +    SSVAL(outbuf,smb_vwv7,passlen);
  606.      p = smb_buf(outbuf);
  607. -    strcpy(p,pass);
  608. -    p += strlen(pass)+1;
  609. +    memcpy(p,pword,passlen);
  610. +    p += passlen;
  611.      strcpy(p,username);
  612.        } else {
  613. +    if (!doencrypt) passlen--;
  614.      /* for Win95 */
  615.      set_message(outbuf,13,0,True);
  616.      CVAL(outbuf,smb_com) = SMBsesssetupX;
  617. @@ -2786,11 +2808,10 @@
  618.      SSVAL(outbuf,smb_vwv3,2);
  619.      SSVAL(outbuf,smb_vwv4,getpid());
  620.      SIVAL(outbuf,smb_vwv5,sesskey);
  621. +    SSVAL(outbuf,smb_vwv7,passlen);
  622.      SSVAL(outbuf,smb_vwv8,0);
  623. -    SSVAL(outbuf,smb_vwv7,strlen(pass));
  624.      p = smb_buf(outbuf);
  625. -    strcpy(p,pass); strupper(p); p += SVAL(outbuf,smb_vwv7);
  626. -    strcpy(p,pass); p += SVAL(outbuf,smb_vwv8);
  627. +    memcpy(p,pword,passlen); p += SVAL(outbuf,smb_vwv7);
  628.      strcpy(p,username);p = skip_string(p,1);
  629.      strcpy(p,WORKGROUP);p = skip_string(p,1);
  630.      strcpy(p,"Unix");p = skip_string(p,1);
  631. @@ -2858,19 +2879,37 @@
  632.  
  633.   again2:
  634.  
  635. -  set_message(outbuf,0,6 + strlen(service) + strlen(pass) + strlen(dev),True);
  636. -  CVAL(outbuf,smb_com) = SMBtcon;
  637. -  setup_pkt(outbuf);
  638. +  {
  639. +    int passlen = strlen(pass);
  640. +    fstring pword;
  641. +    strcpy(pword,pass);
  642. +
  643. +#ifdef SMB_PASSWD
  644. +    if (doencrypt) {
  645. +      passlen=24;
  646. +      SMBencrypt(pass,cryptkey,pword);      
  647. +    }
  648. +#endif
  649.  
  650. -  p = smb_buf(outbuf);
  651. -  *p++ = 4;
  652. -  strcpy(p,service);
  653. -  p += strlen(p) + 1;
  654. -  *p++ = 4;
  655. -  strcpy(p,pass);
  656. -  p += strlen(p) + 1;
  657. -  *p++ = 4;
  658. -  strcpy(p,dev);
  659. +    /* if in user level security then don't send a password now */
  660. +    if ((sec_mode & 1)) {
  661. +      passlen=0;
  662. +    }
  663. +
  664. +    set_message(outbuf,4,2 + strlen(service) + passlen + strlen(dev),True);
  665. +    CVAL(outbuf,smb_com) = SMBtconX;
  666. +    setup_pkt(outbuf);
  667. +
  668. +    SSVAL(outbuf,smb_vwv0,0xFF);
  669. +    SSVAL(outbuf,smb_vwv3,passlen);
  670. +
  671. +    p = smb_buf(outbuf);
  672. +    memcpy(p,pword,passlen);
  673. +    p += passlen;
  674. +    strcpy(p,service);
  675. +    p = skip_string(p,1);
  676. +    strcpy(p,dev);
  677. +  }
  678.  
  679.    send_smb(outbuf);
  680.    receive_smb(inbuf,CLIENT_TIMEOUT);
  681. @@ -2878,16 +2917,17 @@
  682.    /* trying again with a blank password */
  683.    if (CVAL(inbuf,smb_rcls) != 0 && 
  684.        (int)strlen(pass) > 0 && 
  685. +      !doencrypt &&
  686.        Protocol >= PROTOCOL_LANMAN1)
  687.      {
  688. -      DEBUG(0,("first SMBtcon failed, trying again. %s\n",smb_errstr(inbuf)));
  689. +      DEBUG(0,("first SMBtconX failed, trying again. %s\n",smb_errstr(inbuf)));
  690.        strcpy(pass,"");
  691.        goto again2;
  692.      }  
  693.  
  694.    if (CVAL(inbuf,smb_rcls) != 0)
  695.      {
  696. -      DEBUG(0,("SMBtcon failed. %s\n",smb_errstr(inbuf)));
  697. +      DEBUG(0,("SMBtconX failed. %s\n",smb_errstr(inbuf)));
  698.        DEBUG(0,("Perhaps you are using the wrong sharename, username or password?\n"));
  699.        DEBUG(0,("Some servers insist that these be in uppercase\n"));
  700.        if (was_null)
  701. @@ -2904,7 +2944,7 @@
  702.    if (max_xmit <= 0)
  703.      max_xmit = BUFFER_SIZE - 4;
  704.  
  705. -  cnum = SVAL(inbuf,smb_vwv1);
  706. +  cnum = SVAL(inbuf,smb_tid);
  707.  
  708.    DEBUG(3,("Connected with cnum=%d max_xmit=%d\n",cnum,max_xmit));
  709.  
  710. diff -u -r --new-file last-version/source/includes.h samba-1.9.14alpha11/source/includes.h
  711. --- last-version/source/includes.h    Tue Jul 11 13:35:34 1995
  712. +++ samba-1.9.14alpha11/source/includes.h    Tue Jul 11 20:07:18 1995
  713. @@ -772,6 +772,10 @@
  714.  #endif
  715.  #endif
  716.  
  717. +#ifndef perror
  718. +#define perror(s) printf("%s: %s\n",s,strerror(errno))
  719. +#endif
  720. +
  721.  #ifndef MAXHOSTNAMELEN
  722.  #define MAXHOSTNAMELEN 255
  723.  #endif
  724. diff -u -r --new-file last-version/source/password.c samba-1.9.14alpha11/source/password.c
  725. --- last-version/source/password.c    Tue Jul 11 16:45:47 1995
  726. +++ samba-1.9.14alpha11/source/password.c    Tue Jul 11 22:02:55 1995
  727. @@ -508,14 +508,15 @@
  728.  #ifdef SMB_PASSWD
  729.    char challenge[8];
  730.    struct smb_passwd *smb_pass;
  731. -  BOOL challenge_done = last_challenge(challenge);
  732. +  BOOL challenge_done = False;
  733.  #endif
  734.  
  735.  #if DEBUG_PASSWORD
  736.  #ifdef SMB_PASSWD
  737.    int i;
  738. -  if((pwlen == 24) && challenge_done)
  739. +  if ((pwlen == 24) && (challenge_done = last_challenge(challenge)))
  740.      {
  741. +      
  742.        DEBUG(100,("checking user=[%s] pass=[",user));
  743.        for( i = 0; i < 24; i++)
  744.      DEBUG(100,("%0x ", (unsigned char)password[i]));
  745. diff -u -r --new-file last-version/source/smbencrypt.c samba-1.9.14alpha11/source/smbencrypt.c
  746. --- last-version/source/smbencrypt.c    Thu Jan  1 10:00:00 1970
  747. +++ samba-1.9.14alpha11/source/smbencrypt.c    Tue Jul 11 21:56:15 1995
  748. @@ -0,0 +1,115 @@
  749. +#ifdef SMB_PASSWD
  750. +/* 
  751. +   Unix SMB/Netbios implementation.
  752. +   Version 1.9.
  753. +   SMB parameters and setup
  754. +   Copyright (C) Andrew Tridgell 1992-1995
  755. +   Modified by Jeremy Allison 1995.
  756. +   
  757. +   This program is free software; you can redistribute it and/or modify
  758. +   it under the terms of the GNU General Public License as published by
  759. +   the Free Software Foundation; either version 2 of the License, or
  760. +   (at your option) any later version.
  761. +   
  762. +   This program is distributed in the hope that it will be useful,
  763. +   but WITHOUT ANY WARRANTY; without even the implied warranty of
  764. +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  765. +   GNU General Public License for more details.
  766. +   
  767. +   You should have received a copy of the GNU General Public License
  768. +   along with this program; if not, write to the Free Software
  769. +   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  770. +*/
  771. +
  772. +#include "includes.h"
  773. +#include "loadparm.h"
  774. +#include "des.h"
  775. +
  776. +extern int DEBUGLEVEL;
  777. +
  778. +#ifndef uchar
  779. +#define uchar unsigned char
  780. +#endif
  781. +
  782. +void str_to_key(uchar *str,uchar *key)
  783. +{
  784. +  void des_set_odd_parity(des_cblock *);
  785. +  int i;
  786. +
  787. +  key[0] = str[0]>>1;
  788. +  key[1] = ((str[0]&0x01)<<6) | (str[1]>>2);
  789. +  key[2] = ((str[1]&0x03)<<5) | (str[2]>>3);
  790. +  key[3] = ((str[2]&0x07)<<4) | (str[3]>>4);
  791. +  key[4] = ((str[3]&0x0F)<<3) | (str[4]>>5);
  792. +  key[5] = ((str[4]&0x1F)<<2) | (str[5]>>6);
  793. +  key[6] = ((str[5]&0x3F)<<1) | (str[6]>>7);
  794. +  key[7] = str[6]&0x7F;
  795. +  for (i=0;i<8;i++) {
  796. +    key[i] = (key[i]<<1);
  797. +  }
  798. +  des_set_odd_parity((des_cblock *)key);
  799. +}
  800. +
  801. +void D1(uchar *k, uchar *d, uchar *out)
  802. +{
  803. +  des_key_schedule ks;
  804. +  des_cblock deskey;
  805. +
  806. +  str_to_key(k,(uchar *)deskey);
  807. +  des_set_key(deskey,ks);
  808. +  des_ecb_encrypt(d, out, ks, DES_DECRYPT);
  809. +}
  810. +
  811. +void E1(uchar *k, uchar *d, uchar *out)
  812. +{
  813. +  des_key_schedule ks;
  814. +  des_cblock deskey;
  815. +
  816. +  str_to_key(k,(uchar *)deskey);
  817. +  des_set_key(deskey,ks);
  818. +  des_ecb_encrypt(d, out, ks, DES_ENCRYPT);
  819. +}
  820. +void E_P16(uchar *p14,uchar *p16)
  821. +{
  822. +  uchar sp7[7];
  823. +  /* the following constant makes us compatible with other
  824. +  implementations. Note that publishing this constant does not reduce the
  825. +  security of the encryption mechanism */
  826. +  uchar sp8[] = {0xAA,0xD3,0xB4,0x35,0xB5,0x14,0x4,0xEE};
  827. +  uchar x[8];
  828. +
  829. +  memset(sp7,'\0',7);
  830. +
  831. +  D1(sp7, sp8, x);
  832. +  E1(p14, x, p16);
  833. +  E1(p14+7, x, p16+8);
  834. +}
  835. +
  836. +void E_P24(uchar *p21, uchar *c8, uchar *p24)
  837. +{
  838. +  E1(p21, c8, p24);
  839. +  E1(p21+7, c8, p24+8);
  840. +  E1(p21+14, c8, p24+16);
  841. +}
  842. +
  843. +
  844. +/*
  845. +   This implements the X/Open SMB password encryption
  846. +   It takes a password, a 8 byte "crypt key" and puts 24 bytes of 
  847. +   encrypted password into p24 */
  848. +void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24)
  849. +{
  850. +  uchar p14[15], p21[21];
  851. +
  852. +  memset(p21,'\0',21);
  853. +  memset(p14,'\0',14);
  854. +  StrnCpy((char *)p14,(char *)passwd,14);
  855. +
  856. +  strupper((char *)p14);
  857. +  E_P16(p14, p21);
  858. +  E_P24(p21, c8, p24);
  859. +}
  860. +#else
  861. +void smbencrypt_dummy(void){}
  862. +#endif
  863. diff -u -r --new-file last-version/source/smbpass.c samba-1.9.14alpha11/source/smbpass.c
  864. --- last-version/source/smbpass.c    Tue Jul 11 15:15:19 1995
  865. +++ samba-1.9.14alpha11/source/smbpass.c    Tue Jul 11 20:53:22 1995
  866. @@ -23,117 +23,23 @@
  867.  
  868.  #include "includes.h"
  869.  #include "loadparm.h"
  870. -#include "des.h"
  871.  
  872.  extern int DEBUGLEVEL;
  873.  
  874. -#define uchar unsigned char
  875.  
  876. -void str_to_key(uchar *str,uchar *key)
  877. -{
  878. -  int i;
  879. -
  880. -  key[0] = str[0]>>1;
  881. -  key[1] = ((str[0]&0x01)<<6) | (str[1]>>2);
  882. -  key[2] = ((str[1]&0x03)<<5) | (str[2]>>3);
  883. -  key[3] = ((str[2]&0x07)<<4) | (str[3]>>4);
  884. -  key[4] = ((str[3]&0x0F)<<3) | (str[4]>>5);
  885. -  key[5] = ((str[4]&0x1F)<<2) | (str[5]>>6);
  886. -  key[6] = ((str[5]&0x3F)<<1) | (str[6]>>7);
  887. -  key[7] = str[6]&0x7F;
  888. -  for (i=0;i<8;i++) {
  889. -    key[i] = (key[i]<<1);
  890. -  }
  891. -  des_set_odd_parity(key);
  892. -}
  893. -
  894. -void D1(uchar *k, uchar *d, uchar *out)
  895. -{
  896. -  des_key_schedule ks;
  897. -  des_cblock deskey;
  898. -
  899. -  str_to_key(k,(uchar *)deskey);
  900. -  des_set_key(deskey,ks);
  901. -  des_ecb_encrypt(d, out, ks, DES_DECRYPT);
  902. -}
  903. -
  904. -void E1(uchar *k, uchar *d, uchar *out)
  905. -{
  906. -  des_key_schedule ks;
  907. -  des_cblock deskey;
  908. -
  909. -  str_to_key(k,(uchar *)deskey);
  910. -  des_set_key(deskey,ks);
  911. -  des_ecb_encrypt(d, out, ks, DES_ENCRYPT);
  912. -}
  913. -void E_P16(uchar *p14,uchar *p16)
  914. -{
  915. -  uchar sp7[7];
  916. -  uchar sp8[] = {0xAA,0xD3,0xB4,0x35,0xB5,0x14,0x4,0xEE};
  917. -  uchar x[8];
  918. -
  919. -  memset(sp7,'\0',7);
  920. -
  921. -  D1(sp7, sp8, x);
  922. -  E1(p14, x, p16);
  923. -  E1(p14+7, x, p16+8);
  924. -}
  925. -
  926. -void E_P24(uchar *p21, uchar *c8, uchar *p24)
  927. -{
  928. -  E1(p21, c8, p24);
  929. -  E1(p21+7, c8, p24+8);
  930. -  E1(p21+14, c8, p24+16);
  931. -}
  932. -
  933. -
  934. -/*
  935. -   This implements the X/Open SMB password encryption
  936. -   It takes a password, a 8 byte "crypt key" and puts 24 bytes of 
  937. -   encrypted password into p24
  938. -*/
  939. -void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24)
  940. -{
  941. -  uchar p14[14], p21[21];
  942. -
  943. -  memset(p21,'\0',21);
  944. -  memset(p14,'\0',14);
  945. -  strncpy((char *)p14,(char *)passwd,14);
  946. -
  947. -  E_P16(p14, p21);
  948. -  E_P24(p21, c8, p24);
  949. -}
  950. -
  951. -/* Try and get a lock on the first byte of the
  952. -   file. If this fails wait 5 seconds then try again.
  953. -   If this fails then return an error. This ensures a 
  954. -   consistant view is always seen as all processes updating
  955. -   this file should finish within 5 seconds.
  956. -*/
  957. -
  958. -static int gotalarm;
  959. -
  960. -void gotalarm_sig()
  961. -{
  962. -  gotalarm = 1;
  963. -}
  964. -
  965. -/* Static buffers we will return. */
  966. -static struct smb_passwd pw_buf;
  967. -static pstring user_name;
  968. -static unsigned char smbpwd[16];
  969. -
  970.  /*
  971.   * Routine to search the smbpasswd file for an
  972.   * entry matching the username.
  973.   */
  974. -struct smb_passwd *get_smbpwnam(const char *name)
  975. +struct smb_passwd *get_smbpwnam(char *name)
  976.  {
  977. +  /* Static buffers we will return. */
  978. +  static struct smb_passwd pw_buf;
  979. +  static pstring user_name;
  980. +  static unsigned char smbpwd[16];
  981.    char linebuf[256];
  982.    unsigned char c;
  983.    unsigned char *p;
  984. -  unsigned char *newp;
  985.    long uidval;
  986.    long linebuf_len;
  987.    unsigned char lonybble, hinybble;
  988. @@ -164,7 +70,7 @@
  989.    }
  990.  
  991.    /* make sure it is only rw by the owner */
  992. -  fchmod(fileno(fp),0600);
  993. +  chmod(pfile,0600);
  994.    
  995.    /* We have a read lock on the file. */
  996.    /* Scan the file, a line at a time and
  997. @@ -215,7 +121,7 @@
  998.  
  999.        if(linebuf[0] == '#' || linebuf[0] == '\0')
  1000.      {
  1001. -      DEBUG(4,("get_smbpwnam: skipping comment or blank line\n"));
  1002. +      DEBUG(6,("get_smbpwnam: skipping comment or blank line\n"));
  1003.        continue;
  1004.      }
  1005.        p = (unsigned char *)strchr(linebuf, ':');
  1006. @@ -226,74 +132,77 @@
  1007.      }
  1008.        /* As 256 is shorter than a pstring we don't
  1009.       need to check length here - if this ever changes.... */
  1010. -      strncpy( user_name, linebuf, (char *)p - linebuf);
  1011. -      user_name[(char *)p - linebuf] = '\0';
  1012. -      if(strcasecmp(user_name, name))
  1013. +      strncpy(user_name, linebuf, PTR_DIFF(p,linebuf));
  1014. +      user_name[PTR_DIFF(p,linebuf)] = '\0';
  1015. +      if(!strequal(user_name, name))
  1016.      continue;
  1017.  
  1018.        /* User name matches - get uid and password */
  1019.        p++;            /* Go past ':' */
  1020. -      if(!isdigit(*p))
  1021. -    {
  1022. -      DEBUG(0,("get_smbpwnam: malformed password entry (uid not number)\n"));
  1023. -      fclose(fp);
  1024. -      file_unlock(lockfd);
  1025. -      return NULL;
  1026. -    }
  1027. +      if(!isdigit(*p)) {
  1028. +    DEBUG(0,("get_smbpwnam: malformed password entry (uid not number)\n"));
  1029. +    fclose(fp);
  1030. +    file_unlock(lockfd);
  1031. +    return NULL;
  1032. +      }
  1033.  
  1034. -      uidval = strtol((char *)p, (char **)&newp, 10);
  1035. -      if(*newp != ':')
  1036. -    {
  1037. -      DEBUG(0,("get_smbpwnam: malformed password entry (no : after uid)\n"));
  1038. -      fclose(fp);
  1039. -      file_unlock(lockfd);
  1040. -      return NULL;
  1041. -    }
  1042. +      uidval = atoi((char *)p);
  1043. +      while (*p && isdigit(*p)) p++;
  1044. +      if(*p != ':') {
  1045. +    DEBUG(0,("get_smbpwnam: malformed password entry (no : after uid)\n"));
  1046. +    fclose(fp);
  1047. +    file_unlock(lockfd);
  1048. +    return NULL;
  1049. +      }
  1050.  
  1051.        /* Now get the password value - this should be 32 hex digits which
  1052.       are the ascii representations of a 16 byte string. Get two at
  1053.       a time and put them into the password.
  1054.       */
  1055. -      p = newp + 1;
  1056. -      if(*p == '*' || *p == 'X')
  1057. -    {
  1058. -      /* Password deliberately invalid - end here. */
  1059. -      DEBUG(10,("get_smbpwnam: entry invalidated for user %s\n",user_name));
  1060. -      fclose(fp);
  1061. -      file_unlock(lockfd);
  1062. -      return NULL;
  1063. -    }
  1064. -      if(linebuf_len < ((char *)p - linebuf + 33))
  1065. -    {
  1066. -      DEBUG(0,("get_smbpwnam: malformed password entry (passwd too short)\n"));
  1067. -      fclose(fp);
  1068. -      file_unlock(lockfd);
  1069. -      return(False);
  1070. -    }
  1071. +      p++;
  1072. +      if(*p == '*' || *p == 'X') {
  1073. +    /* Password deliberately invalid - end here. */
  1074. +    DEBUG(10,("get_smbpwnam: entry invalidated for user %s\n",user_name));
  1075. +    fclose(fp);
  1076. +    file_unlock(lockfd);
  1077. +    return NULL;
  1078. +      }
  1079. +      if(linebuf_len < (PTR_DIFF(p,linebuf) + 33)) {
  1080. +    DEBUG(0,("get_smbpwnam: malformed password entry (passwd too short)\n"));
  1081. +    fclose(fp);
  1082. +    file_unlock(lockfd);
  1083. +    return(False);
  1084. +      }
  1085.  
  1086. -      if(p[32] != ':')
  1087. -    {
  1088. -      DEBUG(0,("get_smbpwnam: malformed password entry (no terminating :)\n"));
  1089. -      fclose(fp);
  1090. -      file_unlock(lockfd);
  1091. -      return NULL;
  1092. -    }
  1093. +      if(p[32] != ':') {
  1094. +    DEBUG(0,("get_smbpwnam: malformed password entry (no terminating :)\n"));
  1095. +    fclose(fp);
  1096. +    file_unlock(lockfd);
  1097. +    return NULL;
  1098. +      }
  1099.  
  1100. -      if(strncasecmp((char *)p,"NO PASSWORD",11) == 0) {
  1101. +      if (strequal((char *)p,"NO PASSWORD")) {
  1102.      pw_buf.smb_passwd = NULL;
  1103. -      } else {
  1104. +      } else {    
  1105. +    char *hexchars = "0123456789ABCDEF";
  1106. +    char *p1,*p2;
  1107.      for(i = 0; i < 32; i += 2)
  1108.        {
  1109.          hinybble = toupper(p[i]);
  1110. -        if(isdigit(hinybble))
  1111. -          hinybble -= '0';
  1112. -        else
  1113. -          hinybble = (hinybble - 'A') + 10;
  1114.          lonybble = toupper(p[i+1]);
  1115. -        if(isdigit(lonybble))
  1116. -          lonybble -= '0';
  1117. -        else
  1118. -          lonybble = (lonybble - 'A') + 10;
  1119. +        
  1120. +        p1 = strchr(hexchars,hinybble);
  1121. +        p2 = strchr(hexchars,lonybble);
  1122. +        if (!p1 || !p2) {
  1123. +          DEBUG(0,("Malformed password entry (non hex chars)\n"));
  1124. +          fclose(fp);
  1125. +          file_unlock(lockfd);
  1126. +          return NULL;
  1127. +        }
  1128. +
  1129. +        hinybble = PTR_DIFF(p1,hexchars);
  1130. +        lonybble = PTR_DIFF(p2,hexchars);
  1131. +
  1132.          smbpwd[i/2] = (hinybble << 4) | lonybble;
  1133.        }
  1134.      pw_buf.smb_passwd = smbpwd;
  1135. @@ -302,7 +211,7 @@
  1136.        pw_buf.smb_userid = uidval;
  1137.        fclose(fp);
  1138.        file_unlock(lockfd);
  1139. -      DEBUG(5, ("get_smbpwname: returning passwd entry for user %s, uid %d\n",
  1140. +      DEBUG(5,("get_smbpwname: returning passwd entry for user %s, uid %d\n",
  1141.          user_name, uidval));
  1142.        return &pw_buf;
  1143.      }
  1144. @@ -312,5 +221,6 @@
  1145.    return NULL;
  1146.  }
  1147.  #else
  1148. -char smbpass_dummy[1]; /* To avoid compiler complaints */
  1149. +void smbpass_dummy(void){} /* To avoid compiler complaints */
  1150.  #endif
  1151. +
  1152. diff -u -r --new-file last-version/source/smbpass.h samba-1.9.14alpha11/source/smbpass.h
  1153. --- last-version/source/smbpass.h    Tue Jul 11 13:41:27 1995
  1154. +++ samba-1.9.14alpha11/source/smbpass.h    Tue Jul 11 20:08:40 1995
  1155. @@ -29,10 +29,7 @@
  1156.  };
  1157.  
  1158.  /* Return a smb_passwd struct given a user name, 0 if fails. */
  1159. -struct smb_passwd *get_smbpwnam(const char *user);
  1160. -
  1161. -/* Lock the password file */
  1162. -int do_pw_lock(int, int);
  1163. +struct smb_passwd *get_smbpwnam(char *user);
  1164.  
  1165.  #ifndef uchar
  1166.  #define uchar unsigned char
  1167. diff -u -r --new-file last-version/source/smbpasswd.c samba-1.9.14alpha11/source/smbpasswd.c
  1168. --- last-version/source/smbpasswd.c    Tue Jul 11 15:30:14 1995
  1169. +++ samba-1.9.14alpha11/source/smbpasswd.c    Tue Jul 11 20:05:24 1995
  1170. @@ -29,131 +29,133 @@
  1171.  static pstring user_name;
  1172.  static unsigned char smbpwd[16];
  1173.  
  1174. -struct smb_passwd *_my_get_smbpwnam(FILE *fp, const char *name, BOOL *valid_old_pwd, long *pwd_seekpos)
  1175. +struct smb_passwd *_my_get_smbpwnam(FILE *fp,char *name, BOOL *valid_old_pwd, long *pwd_seekpos)
  1176.  {
  1177. -    char linebuf[256];
  1178. -    unsigned char c;
  1179. -    unsigned char *p;
  1180. -    unsigned char *newp;
  1181. -    long uidval;
  1182. -    long linebuf_len;
  1183. -    unsigned char lonybble, hinybble;
  1184. -    int i;
  1185. -
  1186. -    /* Scan the file, a line at a time and
  1187. -       check if the name matches. */
  1188. -    while(!feof(fp)) 
  1189. -      {
  1190. -        linebuf[0] = '\0';
  1191. -        *pwd_seekpos = ftell(fp);
  1192. +  char linebuf[256];
  1193. +  unsigned char c;
  1194. +  unsigned char *p;
  1195. +  long uidval;
  1196. +  long linebuf_len;
  1197. +  unsigned char lonybble, hinybble;
  1198. +  int i;
  1199. +
  1200. +  /* Scan the file, a line at a time and
  1201. +     check if the name matches. */
  1202. +  while(!feof(fp)) 
  1203. +    {
  1204. +      linebuf[0] = '\0';
  1205. +      *pwd_seekpos = ftell(fp);
  1206.  
  1207. -        fgets(linebuf, 256, fp);
  1208. -        if(ferror(fp))
  1209. -            return NULL;
  1210. -
  1211. -        /* Check if the string is terminated with a newline -
  1212. -            if not then we must keep reading and discard until
  1213. -            we get one.
  1214. -        */
  1215. -        linebuf_len = strlen(linebuf);
  1216. -        if(linebuf[linebuf_len-1] != '\n')
  1217. -          {
  1218. -            c = '\0';
  1219. -            while(!ferror(fp) && !feof(fp))
  1220. -              {
  1221. -                c = fgetc(fp);
  1222. -                if(c == '\n')
  1223. -                    break;
  1224. -              }
  1225. -          }
  1226. -        else
  1227. -            linebuf[linebuf_len-1] = '\0';
  1228. -
  1229. -        if((linebuf[0] == 0) && feof(fp))
  1230. -            break;
  1231. -        /* The line we have should be of the form :-
  1232. -
  1233. -        username:uid:[32hex bytes]:....other flags presently ignored....
  1234. -
  1235. -        */
  1236. -
  1237. -        if(linebuf[0] == '#' || linebuf[0] == '\0')
  1238. -            continue;
  1239. -        p = (unsigned char *)strchr(linebuf, ':');
  1240. -        if( p == NULL)
  1241. -            continue;
  1242. -        /* As 256 is shorter than a pstring we don't
  1243. -           need to check length here - if this ever changes.... */
  1244. -        strncpy( user_name, linebuf, (char *)p - linebuf);
  1245. -        user_name[(char *)p - linebuf] = '\0';
  1246. -        if(strcasecmp(user_name, name))
  1247. -            continue;
  1248. -
  1249. -        /* User name matches - get uid and password */
  1250. -        p++; /* Go past ':' */
  1251. -        if(!isdigit(*p))
  1252. -            return(False);
  1253. -
  1254. -        uidval = strtol((char *)p, (char **)&newp, 10);
  1255. -        if(*newp != ':')
  1256. -            return(False);
  1257. -
  1258. -        /* Now get the password value - this should be 32 hex digits which
  1259. -           are the ascii representations of a 16 byte string. Get two at
  1260. -           a time and put them into the password.
  1261. -        */
  1262. -        p = newp + 1;
  1263. -        *pwd_seekpos += ((char *)p - linebuf); /* Save exact position of
  1264. -                         passwd in file - this is used
  1265. -                         by smbpasswd.c 
  1266. -                      */
  1267. -        if(*p == '*' || *p == 'X')
  1268. -          {
  1269. -            /* Password deliberately invalid - end here. */
  1270. -            *valid_old_pwd = False;
  1271. -            pw_buf.smb_name = user_name;
  1272. -            pw_buf.smb_userid = uidval;
  1273. -            return(&pw_buf);
  1274. -          }
  1275. -        if(linebuf_len < ((char *)p - linebuf + 33))
  1276. -            return(False);
  1277. -
  1278. -        if(p[32] != ':')
  1279. -            return(False);
  1280. -
  1281. -        if(strncasecmp(p,"NO PASSWORD",11) == 0) {
  1282. -            pw_buf.smb_passwd = NULL; /* No password */
  1283. -        } else {
  1284. -            for(i = 0; i < 32; i += 2)
  1285. -              {
  1286. -                hinybble = toupper(p[i]);
  1287. -                if(isdigit(hinybble))
  1288. -                    hinybble -= '0';
  1289. -                else
  1290. -                    hinybble = (hinybble - 'A') + 10;
  1291. -                lonybble = toupper(p[i+1]);
  1292. -                if(isdigit(lonybble))
  1293. -                    lonybble -= '0';
  1294. -                else
  1295. -                    lonybble = (lonybble - 'A') + 10;
  1296. -                smbpwd[i/2] = (hinybble << 4) | lonybble;
  1297. -              }
  1298. -            pw_buf.smb_passwd = smbpwd;
  1299. -        }
  1300. -
  1301. -        pw_buf.smb_name = user_name;
  1302. -        pw_buf.smb_userid = uidval;
  1303. -        *valid_old_pwd = True;
  1304. -        return &pw_buf;
  1305. -    }
  1306. +      fgets(linebuf, 256, fp);
  1307. +      if(ferror(fp))
  1308.      return NULL;
  1309. +
  1310. +      /* Check if the string is terminated with a newline -
  1311. +     if not then we must keep reading and discard until
  1312. +     we get one.
  1313. +     */
  1314. +      linebuf_len = strlen(linebuf);
  1315. +      if(linebuf[linebuf_len-1] != '\n')
  1316. +    {
  1317. +      c = '\0';
  1318. +      while(!ferror(fp) && !feof(fp))
  1319. +        {
  1320. +          c = fgetc(fp);
  1321. +          if(c == '\n')
  1322. +        break;
  1323. +        }
  1324. +    }
  1325. +      else
  1326. +    linebuf[linebuf_len-1] = '\0';
  1327. +
  1328. +      if((linebuf[0] == 0) && feof(fp))
  1329. +    break;
  1330. +      /* The line we have should be of the form :-
  1331. +
  1332. +     username:uid:[32hex bytes]:....other flags presently ignored....
  1333. +     */
  1334. +
  1335. +      if(linebuf[0] == '#' || linebuf[0] == '\0')
  1336. +    continue;
  1337. +      p = (unsigned char *)strchr(linebuf, ':');
  1338. +      if( p == NULL)
  1339. +    continue;
  1340. +      /* As 256 is shorter than a pstring we don't
  1341. +     need to check length here - if this ever changes.... */
  1342. +      strncpy( user_name, linebuf, PTR_DIFF(p,linebuf));
  1343. +      user_name[PTR_DIFF(p,linebuf)] = '\0';
  1344. +      if(!strequal(user_name, name))
  1345. +    continue;
  1346. +
  1347. +      /* User name matches - get uid and password */
  1348. +      p++; /* Go past ':' */
  1349. +      if(!isdigit(*p))
  1350. +    return(False);
  1351. +      
  1352. +      uidval = atoi((char *)p);
  1353. +      while (*p && isdigit(*p)) p++;
  1354. +
  1355. +      if(*p != ':')
  1356. +    return(False);
  1357. +      
  1358. +      /* Now get the password value - this should be 32 hex digits which
  1359. +     are the ascii representations of a 16 byte string. Get two at
  1360. +     a time and put them into the password.
  1361. +     */
  1362. +      p++;
  1363. +      *pwd_seekpos += PTR_DIFF(p,linebuf); /* Save exact position of
  1364. +                          passwd in file - this is used
  1365. +                          by smbpasswd.c 
  1366. +                          */
  1367. +      if(*p == '*' || *p == 'X')
  1368. +    {
  1369. +      /* Password deliberately invalid - end here. */
  1370. +      *valid_old_pwd = False;
  1371. +      pw_buf.smb_name = user_name;
  1372. +      pw_buf.smb_userid = uidval;
  1373. +      return(&pw_buf);
  1374. +    }
  1375. +      if(linebuf_len < (PTR_DIFF(p,linebuf) + 33))
  1376. +    return(False);
  1377. +      
  1378. +      if(p[32] != ':')
  1379. +    return(False);
  1380. +
  1381. +      if(strequal(p,"NO PASSWORD")) {
  1382. +    pw_buf.smb_passwd = NULL; /* No password */
  1383. +      } else {
  1384. +    char *hexchars = "0123456789ABCDEF";
  1385. +    char *p1,*p2;    
  1386. +    for(i = 0; i < 32; i += 2)
  1387. +      {
  1388. +        hinybble = toupper(p[i]);
  1389. +        lonybble = toupper(p[i+1]);
  1390. +        
  1391. +        p1 = strchr(hexchars,hinybble);
  1392. +        p2 = strchr(hexchars,lonybble);
  1393. +        if (!p1 || !p2)
  1394. +          return(False);
  1395. +
  1396. +        hinybble = PTR_DIFF(p1,hexchars);
  1397. +        lonybble = PTR_DIFF(p2,hexchars);
  1398. +
  1399. +        smbpwd[i/2] = (hinybble << 4) | lonybble;
  1400. +      }
  1401. +    pw_buf.smb_passwd = smbpwd;
  1402. +      }
  1403. +      
  1404. +      pw_buf.smb_name = user_name;
  1405. +      pw_buf.smb_userid = uidval;
  1406. +      *valid_old_pwd = True;
  1407. +      return &pw_buf;
  1408. +    }
  1409. +  return NULL;
  1410.  }
  1411.  
  1412.  /*
  1413.   * Print command usage on stderr and die.
  1414.   */
  1415. -
  1416. -void usage(const char *name)
  1417. +void usage(char *name)
  1418.  {
  1419.      fprintf(stderr, "Usage is : %s [username]\n", name);
  1420.      exit(1);
  1421. @@ -161,199 +163,199 @@
  1422.  
  1423.  int main(int argc, char **argv)
  1424.  {
  1425. -    int real_uid;
  1426. -    struct passwd *pwd;
  1427. -    fstring old_passwd;
  1428. -    uchar old_p16[16];
  1429. -    fstring new_passwd;
  1430. -    uchar new_p16[16];
  1431. -    char *p;
  1432. -    struct smb_passwd *smb_pwent;
  1433. -    FILE *fp;
  1434. -    BOOL valid_old_pwd = False;
  1435. -    long seekpos;
  1436. -    int pwfd;
  1437. -    char ascii_p16[33];
  1438. -    char c;
  1439. -    int ret, i, err;
  1440. -    int lockfd=-1;
  1441. -    char *pfile = SMB_PASSWD_FILE;
  1442. +  int real_uid;
  1443. +  struct passwd *pwd;
  1444. +  fstring old_passwd;
  1445. +  uchar old_p16[16];
  1446. +  fstring new_passwd;
  1447. +  uchar new_p16[16];
  1448. +  char *p;
  1449. +  struct smb_passwd *smb_pwent;
  1450. +  FILE *fp;
  1451. +  BOOL valid_old_pwd = False;
  1452. +  long seekpos;
  1453. +  int pwfd;
  1454. +  char ascii_p16[33];
  1455. +  char c;
  1456. +  int ret, i, err;
  1457. +  int lockfd=-1;
  1458. +  char *pfile = SMB_PASSWD_FILE;
  1459.  
  1460. -    charset_initialise();
  1461. +  charset_initialise();
  1462.  
  1463.  #ifndef DEBUG_PASSWORD
  1464. -    /* Check the effective uid */
  1465. -    if(geteuid() != 0) {
  1466. -        fprintf(stderr, "%s: Must be setuid root.\n", argv[0]);
  1467. -        exit(1);
  1468. -    }
  1469. +  /* Check the effective uid */
  1470. +  if(geteuid() != 0) {
  1471. +    fprintf(stderr, "%s: Must be setuid root.\n", argv[0]);
  1472. +    exit(1);
  1473. +  }
  1474.  #endif
  1475.  
  1476. -    /* Get the real uid */
  1477. -    real_uid = getuid();
  1478. -
  1479. -    /* Deal with usage problems */
  1480. -    if( real_uid == 0) {
  1481. -        /* As root we can change anothers password. */
  1482. -        if(argc != 1 && argc != 2)
  1483. -            usage(argv[0]);
  1484. -    } else if(argc != 1)
  1485. -        usage(argv[0]);
  1486. +  /* Get the real uid */
  1487. +  real_uid = getuid();
  1488. +  
  1489. +  /* Deal with usage problems */
  1490. +  if( real_uid == 0) {
  1491. +    /* As root we can change anothers password. */
  1492. +    if(argc != 1 && argc != 2)
  1493. +      usage(argv[0]);
  1494. +  } else if(argc != 1)
  1495. +    usage(argv[0]);
  1496.          
  1497.  
  1498. -    if(real_uid == 0 && argc == 2) {
  1499. -        /* If we are root we can change anothers password. */
  1500. -        strncpy( user_name, argv[1], sizeof(user_name)-1);
  1501. -        user_name[sizeof(user_name)-1] = '\0';
  1502. -        pwd = getpwnam( user_name );
  1503. -    } else {
  1504. -        pwd = getpwuid( real_uid );
  1505. -    }
  1506. -
  1507. -    if(pwd == 0) {
  1508. -        fprintf(stderr, "%s: Unable to get UNIX password entry for user.\n", argv[0]);
  1509. -        exit(1);
  1510. -    }
  1511. -
  1512. -    /* If we are root we don't ask for the old password. */
  1513. -    old_passwd[0] = '\0';
  1514. -    if(real_uid != 0) {
  1515. -        p = getpass("Old SMB password:");
  1516. -        strncpy(old_passwd, p, 14);
  1517. -        old_passwd[14] = '\0';
  1518. -        strupper(old_passwd);
  1519. -    }
  1520. -
  1521. -    new_passwd[0] = '\0';
  1522. -    p = getpass("New SMB password:");
  1523. -    strncpy(new_passwd, p, 14);
  1524. -    new_passwd[14] = '\0';
  1525. -    p = getpass("Retype new SMB password:");
  1526. -    if(strncmp(p, new_passwd, 14)) {
  1527. -        fprintf(stderr, "%s: Mismatch - password unchanged.\n", argv[0]);
  1528. -        exit(1);
  1529. -    }
  1530. -    strupper(new_passwd);
  1531. -
  1532. -    if(new_passwd[0] == '\0') {
  1533. -        printf("Password not set\n");
  1534. -        exit(0);
  1535. -    }
  1536. -
  1537. -    /* Calculate the SMB hash functions of
  1538. -       both old an new passwords. */
  1539. -
  1540. -    memset(old_p16,'\0',16);
  1541. -    E_P16((uchar *)old_passwd,old_p16);
  1542. -
  1543. -    memset(new_p16,'\0',16);
  1544. -    E_P16((uchar *)new_passwd,new_p16);
  1545. -
  1546. -    /* Open the smbpaswd file XXXX - we need to parse smb.conf to
  1547. -           get the filename */
  1548. -    if((fp = fopen(pfile, "r+")) == NULL) {
  1549. -        err = errno;
  1550. -        fprintf(stderr, "%s: Failed to open password file %s.\n", 
  1551. -            argv[0], pfile);
  1552. -        errno = err;
  1553. -        perror(argv[0]);
  1554. -        exit(err);
  1555. -    }
  1556. -
  1557. -    /* make sure it is only rw by the owner */
  1558. -    fchmod(fileno(fp),0600);
  1559. -    
  1560. -    /* Lock the smbpasswd file for write. */
  1561. -    if((lockfd=file_lock(pfile,5))<0) {
  1562. -        err = errno;
  1563. -        fprintf(stderr, "%s: Failed to lock password file %s.\n", 
  1564. -            argv[0], pfile);
  1565. -        fclose(fp);
  1566. -        errno = err;
  1567. -        perror(argv[0]);
  1568. -        exit(err);
  1569. -    }
  1570. -
  1571. -    /* Get the smb passwd entry for this user */
  1572. -    smb_pwent = _my_get_smbpwnam( fp, pwd->pw_name, &valid_old_pwd, &seekpos);
  1573. -    if(smb_pwent == NULL) {
  1574. -        fprintf(stderr, "%s: Failed to find entry for user %s in file %s.\n",
  1575. -                argv[0], pwd->pw_name, pfile);
  1576. -        fclose(fp);
  1577. -        file_unlock(lockfd);
  1578. -        exit(1);
  1579. -    }
  1580. -
  1581. -    /* If we are root we don't need to check the old password. */
  1582. -    if( real_uid != 0) {
  1583. -        if( valid_old_pwd == False) {
  1584. -            fprintf(stderr, "%s: User %s is disabled, plase contact your administrator to enable it.\n", argv[0], pwd->pw_name);
  1585. -            fclose(fp);
  1586. -            file_unlock(lockfd);
  1587. -            exit(1);
  1588. -        }
  1589. -        /* Check the old passwd (if there was one). */
  1590. -        if(smb_pwent->smb_passwd != NULL) {
  1591. -            if( memcmp( old_p16, smb_pwent->smb_passwd, 16)) {
  1592. -                fprintf(stderr, "%s: Couldn't change password.\n", argv[0]);
  1593. -                fclose(fp);
  1594. -                file_unlock(lockfd);
  1595. -                exit(1);
  1596. -            }
  1597. -        }
  1598. -    }
  1599. -    /* If we get here either we were root or the old password
  1600. -        checked out ok. */
  1601. -    /* Create the 32 byte representation of the new p16 */
  1602. -    for(i = 0; i < 16; i++) {
  1603. -        sprintf(&ascii_p16[i*2], "%02X", (uchar)new_p16[i]);
  1604. -    }
  1605. -    /* Do an atomic write into the file at the position
  1606. -       defined by seekpos. */
  1607. -    pwfd = fileno(fp);
  1608. -    ret = lseek(pwfd, seekpos - 1, SEEK_SET);
  1609. -    if(ret != seekpos -1) {
  1610. -        err = errno;
  1611. -        fprintf(stderr, "%s: seek fail on file %s.\n", 
  1612. -            argv[0], pfile);
  1613. -        fclose(fp);
  1614. -        errno = err;
  1615. -        perror(argv[0]);
  1616. -        file_unlock(lockfd);
  1617. -        exit(1);
  1618. -    }
  1619. -    /* Sanity check - ensure the character is a ':' */
  1620. -    if(read(pwfd,&c,1) != 1) {
  1621. -        err = errno;
  1622. -        fprintf(stderr, "%s: read fail on file %s.\n", 
  1623. -            argv[0], pfile);
  1624. -        fclose(fp);
  1625. -        errno = err;
  1626. -        perror(argv[0]);
  1627. -        file_unlock(lockfd);
  1628. -        exit(1);
  1629. -    }
  1630. -    if(c != ':') {
  1631. -        fprintf(stderr, "%s: sanity check on passwd file %s failed.\n",
  1632. -            argv[0], pfile);
  1633. -        fclose(fp);
  1634. -        file_unlock(lockfd);
  1635. -        exit(1);
  1636. -    }
  1637. -    if(write(pwfd,ascii_p16,32)!=32) {
  1638. -        err = errno;
  1639. -        fprintf(stderr, "%s: write fail in file %s.\n", 
  1640. -            argv[0], pfile);
  1641. -        fclose(fp);
  1642. -        errno = err;
  1643. -        perror(argv[0]);
  1644. -        file_unlock(lockfd);
  1645. -        exit(err);
  1646. -    }
  1647. +  if(real_uid == 0 && argc == 2) {
  1648. +    /* If we are root we can change anothers password. */
  1649. +    strncpy( user_name, argv[1], sizeof(user_name)-1);
  1650. +    user_name[sizeof(user_name)-1] = '\0';
  1651. +    pwd = getpwnam( user_name );
  1652. +  } else {
  1653. +    pwd = getpwuid( real_uid );
  1654. +  }
  1655. +
  1656. +  if(pwd == 0) {
  1657. +    fprintf(stderr, "%s: Unable to get UNIX password entry for user.\n", argv[0]);
  1658. +    exit(1);
  1659. +  }
  1660. +  
  1661. +  /* If we are root we don't ask for the old password. */
  1662. +  old_passwd[0] = '\0';
  1663. +  if(real_uid != 0) {
  1664. +    p = getpass("Old SMB password:");
  1665. +    strncpy(old_passwd, p, 14);
  1666. +    old_passwd[14] = '\0';
  1667. +    strupper(old_passwd);
  1668. +  }
  1669. +  
  1670. +  new_passwd[0] = '\0';
  1671. +  p = getpass("New SMB password:");
  1672. +  strncpy(new_passwd, p, 14);
  1673. +  new_passwd[14] = '\0';
  1674. +  p = getpass("Retype new SMB password:");
  1675. +  if(strncmp(p, new_passwd, 14)) {
  1676. +    fprintf(stderr, "%s: Mismatch - password unchanged.\n", argv[0]);
  1677. +    exit(1);
  1678. +  }
  1679. +  strupper(new_passwd);
  1680. +  
  1681. +  if(new_passwd[0] == '\0') {
  1682. +    printf("Password not set\n");
  1683. +    exit(0);
  1684. +  }
  1685. +  
  1686. +  /* Calculate the SMB hash functions of
  1687. +     both old an new passwords. */
  1688. +  
  1689. +  memset(old_p16,'\0',16);
  1690. +  E_P16((uchar *)old_passwd,old_p16);
  1691. +  
  1692. +  memset(new_p16,'\0',16);
  1693. +  E_P16((uchar *)new_passwd,new_p16);
  1694. +  
  1695. +  /* Open the smbpaswd file XXXX - we need to parse smb.conf to
  1696. +     get the filename */
  1697. +  if((fp = fopen(pfile, "r+")) == NULL) {
  1698. +    err = errno;
  1699. +    fprintf(stderr, "%s: Failed to open password file %s.\n", 
  1700. +        argv[0], pfile);
  1701. +    errno = err;
  1702. +    perror(argv[0]);
  1703. +    exit(err);
  1704. +  }
  1705. +  
  1706. +  /* make sure it is only rw by the owner */
  1707. +  chmod(pfile,0600);
  1708. +  
  1709. +  /* Lock the smbpasswd file for write. */
  1710. +  if((lockfd=file_lock(pfile,5))<0) {
  1711. +    err = errno;
  1712. +    fprintf(stderr, "%s: Failed to lock password file %s.\n", 
  1713. +        argv[0], pfile);
  1714. +    fclose(fp);
  1715. +    errno = err;
  1716. +    perror(argv[0]);
  1717. +    exit(err);
  1718. +  }
  1719. +
  1720. +  /* Get the smb passwd entry for this user */
  1721. +  smb_pwent = _my_get_smbpwnam(fp, pwd->pw_name, &valid_old_pwd, &seekpos);
  1722. +  if(smb_pwent == NULL) {
  1723. +    fprintf(stderr, "%s: Failed to find entry for user %s in file %s.\n",
  1724. +        argv[0], pwd->pw_name, pfile);
  1725. +    fclose(fp);
  1726. +    file_unlock(lockfd);
  1727. +    exit(1);
  1728. +  }
  1729. +  
  1730. +  /* If we are root we don't need to check the old password. */
  1731. +  if( real_uid != 0) {
  1732. +    if( valid_old_pwd == False) {
  1733. +      fprintf(stderr, "%s: User %s is disabled, plase contact your administrator to enable it.\n", argv[0], pwd->pw_name);
  1734. +      fclose(fp);
  1735. +      file_unlock(lockfd);
  1736. +      exit(1);
  1737. +    }
  1738. +    /* Check the old passwd (if there was one). */
  1739. +    if(smb_pwent->smb_passwd != NULL) {
  1740. +      if( memcmp( old_p16, smb_pwent->smb_passwd, 16)) {
  1741. +    fprintf(stderr, "%s: Couldn't change password.\n", argv[0]);
  1742.      fclose(fp);
  1743.      file_unlock(lockfd);
  1744. -    printf("Password changed\n");
  1745. -    return 0;
  1746. +    exit(1);
  1747. +      }
  1748. +    }
  1749. +  }
  1750. +  /* If we get here either we were root or the old password
  1751. +     checked out ok. */
  1752. +  /* Create the 32 byte representation of the new p16 */
  1753. +  for(i = 0; i < 16; i++) {
  1754. +    sprintf(&ascii_p16[i*2], "%02X", (uchar)new_p16[i]);
  1755. +  }
  1756. +  /* Do an atomic write into the file at the position
  1757. +     defined by seekpos. */
  1758. +  pwfd = fileno(fp);
  1759. +  ret = lseek(pwfd, seekpos - 1, SEEK_SET);
  1760. +  if(ret != seekpos -1) {
  1761. +    err = errno;
  1762. +    fprintf(stderr, "%s: seek fail on file %s.\n", 
  1763. +        argv[0], pfile);
  1764. +    fclose(fp);
  1765. +    errno = err;
  1766. +    perror(argv[0]);
  1767. +    file_unlock(lockfd);
  1768. +    exit(1);
  1769. +  }
  1770. +  /* Sanity check - ensure the character is a ':' */
  1771. +  if(read(pwfd,&c,1) != 1) {
  1772. +    err = errno;
  1773. +    fprintf(stderr, "%s: read fail on file %s.\n", 
  1774. +        argv[0], pfile);
  1775. +    fclose(fp);
  1776. +    errno = err;
  1777. +    perror(argv[0]);
  1778. +    file_unlock(lockfd);
  1779. +    exit(1);
  1780. +  }
  1781. +  if(c != ':') {
  1782. +    fprintf(stderr, "%s: sanity check on passwd file %s failed.\n",
  1783. +        argv[0], pfile);
  1784. +    fclose(fp);
  1785. +    file_unlock(lockfd);
  1786. +    exit(1);
  1787. +  }
  1788. +  if(write(pwfd,ascii_p16,32)!=32) {
  1789. +    err = errno;
  1790. +    fprintf(stderr, "%s: write fail in file %s.\n", 
  1791. +        argv[0], pfile);
  1792. +    fclose(fp);
  1793. +    errno = err;
  1794. +    perror(argv[0]);
  1795. +    file_unlock(lockfd);
  1796. +    exit(err);
  1797. +  }
  1798. +  fclose(fp);
  1799. +  file_unlock(lockfd);
  1800. +  printf("Password changed\n");
  1801. +  return 0;
  1802.  }
  1803.  
  1804.  #else
  1805. @@ -366,3 +368,5 @@
  1806.    return 0;
  1807.  }
  1808.  #endif
  1809. +
  1810. +
  1811. diff -u -r --new-file last-version/source/version.h samba-1.9.14alpha11/source/version.h
  1812. --- last-version/source/version.h    Tue Jul 11 16:47:52 1995
  1813. +++ samba-1.9.14alpha11/source/version.h    Tue Jul 11 22:38:46 1995
  1814. @@ -1 +1 @@
  1815. -#define VERSION "1.9.14alpha10"
  1816. +#define VERSION "1.9.14alpha11"
  1817.